﻿using ASmile.Com;
using ASmile.Extend;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.Json;
using Microsoft.Extensions.DependencyInjection;
using Swashbuckle.AspNetCore.Filters;
using Swashbuckle.AspNetCore.SwaggerGen;
using Swashbuckle.AspNetCore.SwaggerUI;
using System;
using System.IO;
using System.Reflection;

namespace ASmile.Web
{
    /// <summary>
    /// NETCore 3.1 的自定义配置
    /// </summary>
    public static class GlobalServiceConfig
    {
        public static IConfigurationRoot ConfigRoot { get; private set; }

        public static void InitConfigFile()
        {
            var builder = new ConfigurationBuilder();
            
            builder.Add(new JsonConfigurationSource { Path = "appsettings.json", ReloadOnChange = true });
            ConfigRoot = builder.Build();
            ConfigRoot.Bind("CommonConfig", Config.THIS);
            var m = new ConfigCom();
            ConfigRoot.Bind("CommonConfig", m);
            ConfigCom.Set(m);
            if (ConfigCom.M.LogDbConnStr.IsNotEmpty())
            {
                //LogHelper.SetAdoAppenderConnStr(CommonConfig.THIS.LogDbConnStr);
                LogHelper.ResetConfigure();
            }
        }

        public static IServiceCollection InitCustomService(this IServiceCollection services, Action<IConfigurationRoot> ConfigHandle = null)
        {
            InitConfigFile();

            ConfigHandle?.Invoke(ConfigRoot);
                        
            services                
                .AddControllersWithViews((options) =>
                {
                    options.Filters.Add<GlobalExceptionsFilter>();
                })
                .ConfigureApplicationPartManager((manager) =>
                {
                    //增加其它程序集中的controller
                    var assembly = typeof(GlobalServiceConfig).Assembly;
                    manager.ApplicationParts.Add(new AssemblyPart(assembly));
                })
                //.AddNewtonsoftJson((opt)=> 
                //{
                //    使用中文编码问题没有问题
                //    opt.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver();//json字符串原样输出
                //})
                //.AddMvc()
                .InitJsonOptions();
            return services;
        }

        public static IMvcBuilder InitJsonOptions(this IMvcBuilder builder, Action<JsonOptions> setupAction = null)
        {
            return
            builder
                .AddJsonOptions((options) =>
                 {
                     JsonHelper.SetJsonOption(options);                     
                 });
        }

        /// <summary>
        /// 初始化Swagger
        /// </summary>
        public static IServiceCollection InitSwagger(this IServiceCollection services, Action<SwaggerGenOptions> setupAction)
        {
            if (!Config.THIS.SwaggerEnable)
            {
                return services;
            }

            return
            services.AddSwaggerGen(c =>
            {
                setupAction?.Invoke(c);
                //c.SwaggerDoc("V-Com", new Microsoft.OpenApi.Models.OpenApiInfo
                //{
                //    Title = "框架共通",
                //});
                //c.SwaggerDoc("SysManage", new Microsoft.OpenApi.Models.OpenApiInfo
                //{
                //    Title = "系统管理",
                //});

                c.OperationFilter<SwaggerOperationFilter>();

                c.OperationFilter<AddResponseHeadersFilter>();

                c.OperationFilter<AppendAuthorizeToSummaryOperationFilter>();

                c.OperationFilter<SecurityRequirementsOperationFilter>();

                // 为 Swagger JSON and UI设置xml文档注释路径                
                //获取当前程序的
                var fileName = Assembly.GetEntryAssembly().Location;
                var path = Path.GetDirectoryName(fileName);
                var xmlFiles = Config.THIS.SwaggerXmlComments.Split(',');
                foreach (var xmlFile in xmlFiles)
                {
                    c.IncludeXmlComments(Path.Combine(path, xmlFile));
                }

                c.DocumentFilter<SwaggerHiddenFilter>();
            });
        }

        public static IApplicationBuilder InitAppBuiler(this IApplicationBuilder app)
        {
            app.UseMiddleware<GlobalExceptionMiddleware>();

            //认证中间件必须放在使用MVC中间件之前
            //app.UseAuthentication();

            app.UseStaticFiles();

            //#if DEBUG
            //            app.UseStaticFiles();
            //#else
            //            app.UseStaticFiles(Path.Combine(AppContext.BaseDirectory, @"wwwroot"));
            //#endif
            // 设置允许所有来源跨域
            app.UseCors(options =>
            {
                options.AllowAnyHeader();
                //options.AllowAnyMethod();
                //options.AllowAnyOrigin();
                //options.AllowCredentials();
            });

            return app;
        }
        /// <summary>
        /// 初始化swaggeer app
        /// </summary>
        public static IApplicationBuilder InitSwaggerApp(this IApplicationBuilder app, Action<SwaggerUIOptions> setupAction = null)
        {
            if (!Config.THIS.SwaggerEnable) return app;

            var prefix = Config.THIS.SwaggerRoutePrefix;
            //app.UseMvc(routes =>
            //{
            //    routes.MapRoute(
            //        name: "swagger",
            //        template: "/swagger");
            //});

            //启用中间件服务生成Swagger作为JSON终结点
            app.UseSwagger();
            //启用中间件服务对swagger-ui，指定Swagger JSON终结点
            app.UseSwaggerUI(c =>
            {
                setupAction?.Invoke(c);
                c.RoutePrefix = $"{prefix}"; //如果在主页显示，则改为：Empty，区分大小写
            });
            return app;
        }
    }
}